package com.zhaotianhao.controller;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.zhaotianhao.common.AjaxResult;
import com.zhaotianhao.pojo.Brands;
import com.zhaotianhao.pojo.Cats;
import com.zhaotianhao.pojo.Goods;
import com.zhaotianhao.pojo.Users;
import com.zhaotianhao.service.BrandsService;
import com.zhaotianhao.service.CatsService;
import com.zhaotianhao.service.FilesService;
import com.zhaotianhao.service.GoodsService;
import com.zhaotianhao.util.FileUtils;
import com.zhaotianhao.util.GoodsRepository;
import com.zhaotianhao.util.HighLightResultMapper;
import com.zhaotianhao.util.PDFUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * @Author Z-7
 * @Date 2022/3/2
 */
@Controller
@RequestMapping("goods")
public class GoodsController {
    @DubboReference
    private GoodsService goodsService;
    @DubboReference
    private FilesService filesService;
    @DubboReference
    private CatsService catsService;
    @DubboReference
    private BrandsService brandsService;
    @Resource
    private GoodsRepository goodsRepository;
    @Resource
    private RedisTemplate redisTemplate;
    @Resource
    private KafkaTemplate kafkaTemplate;
    @Resource
    private ElasticsearchTemplate elasticsearchTemplate;

    /**
     * 预热缓存首页
     */
    @PostConstruct
    public void preheat(){
        PageInfo<Goods> manage = (PageInfo<Goods>) redisTemplate.opsForValue().get("manage");
        if(manage == null){
            manage = goodsService.queryByPage(null, 1, 3);
            redisTemplate.opsForValue().set("manage",manage,10, TimeUnit.MINUTES);
        }
    }
    @RequestMapping("list")
    public String to_list(@RequestParam(defaultValue = "1")int pageNum, @RequestParam(defaultValue = "3")int pageSize, Model model){
        PageInfo<Goods> page = (PageInfo<Goods>) redisTemplate.opsForValue().get("manage");
        if(pageNum == 1 && page == null){
            page = goodsService.queryByPage(null, 1, 3);
            redisTemplate.opsForValue().set("manage",page,10, TimeUnit.MINUTES);
        }else{
            page = goodsService.queryByPage(null, pageNum, pageSize);
        }
        page.getList().stream().forEach(System.out::println);
        model.addAttribute("page",page);
        return "goods/goods_list";
    }
    @RequestMapping("addGoods")
    public @ResponseBody boolean addGoods(Goods goods, Long pictureId , HttpSession session){
        System.out.println(goods);
        Users login_usre = (Users) session.getAttribute("LOGIN_USER");
        goods.setCreator(login_usre.getId());
        Goods newGoods = goodsService.insert(goods);
        if(newGoods != null){
            filesService.deleteById(pictureId);
            System.out.println("嘀哩嘀哩:增加成功 发送kafka消息");
            String s = UUID.randomUUID().toString();
            kafkaTemplate.send("1909a","edit",s);
            // es增量同步
            Goods esGoods = goodsService.queryById(newGoods.getId());
            goodsRepository.save(esGoods);
            return true;
        }
        return false;
    }
    @RequestMapping("exportPDF")
    public void exprotPDF(@RequestParam(defaultValue = "1")int pageNum, @RequestParam(defaultValue = "1000")int pageSize,@RequestParam int mode, HttpServletResponse response) throws Exception {
        PageInfo<Goods> page = goodsService.queryByPage(null, pageNum, pageSize);
        Document document = new Document();
        String pdfName = UUID.randomUUID() + ".pdf";
        PdfWriter pdfWriter = PDFUtils.createDoc(document, "d:/mypdf/" + pdfName);
        List<String> list = new ArrayList<>();
        list.add("豪哥商城商品列表");
        PDFUtils.addContent(document,list,20);
        PDFUtils.addTable(pdfWriter,new String[] {"商品编号","商品名称","品牌","分类"},new String[] {"id","name","brandName","catName"},page.getList(),40,600);
        document.close();
        pdfWriter.close();
        // 添加水印
        PDFUtils.markImage("G:\\img\\323743.jpg",new FileInputStream("d:/mypdf/"+pdfName),new FileOutputStream("d:/mypdf1/"+pdfName),"版权所有");
        //下载文件
        FileUtils.download(response,"d:/mypdf1/"+pdfName , "豪哥商城商品列表.pdf",mode);
    }
    @RequestMapping("to_del")
    public @ResponseBody boolean to_del(Integer id){
        boolean b = goodsService.deleteById(id);
        if(b){
            String s = UUID.randomUUID().toString();
            // 增量

            goodsRepository.deleteById(id);
            kafkaTemplate.send("1909a","edit",s);
            return true;
        }
        return false;
    }
    @RequestMapping("to_update")
    public String to_update(Integer id ,HttpServletRequest request){
        Goods goods = goodsService.queryById(id);
        List<Brands> brands = brandsService.queryAll();
        List<Cats> cats = catsService.queryAll();
        request.setAttribute("brands",brands);
        request.setAttribute("cats",cats);
        request.setAttribute("goods",goods);
        return "goods/update";
    }
    @RequestMapping("updateGood")
    public @ResponseBody AjaxResult updateGood(Goods goods){
        int update = goodsService.update(goods);
        if(update > 0){
            String s = UUID.randomUUID().toString();
            kafkaTemplate.send("1909a","edit",s);
            // 增量同步
            Goods esGoods = goodsService.queryById(goods.getId());
            goodsRepository.save(esGoods);
            return new AjaxResult("200","",null);
        }
        return new AjaxResult("400","修改失败",goods.getId());
    }
    @RequestMapping("esList")
    public String esSearch(String name,Double min,Double max,@RequestParam(defaultValue = "1")int pageNum, @RequestParam(defaultValue = "3")int pageSize,Model model){
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        if(StringUtils.hasText(name)){
            System.out.println("name");
            boolQuery.must(QueryBuilders.multiMatchQuery(name,"name"));
        }
        if (min != null) {
            System.out.println("min");

            boolQuery.must(QueryBuilders.rangeQuery("price").gte(min));
        }
        if (max != null) {
            System.out.println("max");

            boolQuery.must(QueryBuilders.rangeQuery("price").lte(max));
        }
        HighlightBuilder.Field hight = new HighlightBuilder.Field("name").preTags("<span style='color:red'>").postTags("</span>");
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQuery)
                .withSort(SortBuilders.fieldSort("id").order(SortOrder.ASC))
                .withHighlightFields(hight)
                .withPageable(PageRequest.of(pageNum - 1, pageSize))
                .build();
        AggregatedPage<Goods> goods = elasticsearchTemplate.queryForPage(searchQuery, Goods.class, new HighLightResultMapper());
        Page page = new Page(pageNum, pageSize);
        page.setTotal(goods.getTotalElements());
        PageInfo<Goods> pageInfo = new PageInfo<Goods>(page);
        pageInfo.setList(goods.getContent());
        model.addAttribute("page",pageInfo);
        model.addAttribute("name",name);
        model.addAttribute("min",min);
        model.addAttribute("max",max);
        return "goods/goods_list";
    }
}
